﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using JetBrains.Annotations;
using UnityEngine;

public partial class CyberU
{
    #region Log

    public static Exception Snot(object _)
    {
        return new Exception($"{_}\n{(string)_}");
    }

    public static void Delog(params object[] messages)
    {
        if (messages == null)
        {
            Debug.Log("null");
            return;
        }

        string combinedMessage = string.Empty;
        foreach (var msg in messages)
        {
            string value = Delogged(msg);
            combinedMessage += value + " ";
        }

        if (combinedMessage.Length > 0)
        {
            combinedMessage = combinedMessage.TrimEnd();
        }
        Debug.Log(combinedMessage);
    }

    public static string Delogged(object msg)
    {
        string value;
        if (msg == null)
        {
            value = "null";
        }
        else if (msg is string str && str.Length == 0)
        {
            value = "\"\"";
        }
        else
        {
            value = msg.ToString();
        }

        return value;
    }
    public static void Deloga(params object[] messages)
    {
        Delog(InsertArray(messages,0,"a"));
    }

    public static void Delogd(params object[] messages)
    {
        Delog(InsertArray(messages,0,"d"));
    }
    public static void Delogz(params object[] messages)
    {
        Delog(InsertArray(messages,0,"z"));
    }

    public static void Delogf(params object[] messages)
    {
        Delog(InsertArray(messages,0,"f"));
    }

    public static T[] InsertArray<T>(T[] array, int index, T value)
    {
        if (array == null)
        {
            return new T[] { value }; // 如果输入为 null，返回只包含新值的数组
        }
        T[] result = new T[array.Length + 1];
        Array.Copy(array, 0, result, 0, index);
        result[index] = value;
        Array.Copy(array, index, result, index + 1, array.Length - index);
        return result;
    }
    public static void Delogc(params object[] messages)
    {
        Delog(InsertArray(messages,0,"c"));
    }

    public static void Delogb(params object[] messages)
    {
        Delog(InsertArray(messages,0,"b"));
    }

    public static void Deloge(params object[] messages)
    {
        Delog(InsertArray(messages,0,"e"));
    }

    public static void DelogHere(params object[] messages)
    {
        Delog(InsertArray(messages,0,"Here"));
    }

    public static void Delog(object message)
    {
        stupid.Debug.Log(Delogged(message));
    }

    public static void DelogType(object _)
    {
        if (_ == null)
        {
            Delog("Object is null");
            return;
        }

        Type type = _.GetType();
        string typeName = type.FullName;
        if (_ is Component comp)
        {
            stupid.Debug.Log($"Component Type: {typeName} | GameObject: {comp.gameObject.name}");
        }
        else if (_ is GameObject go)
        {
            Delog($"GameObject: {go.name}");
        }
        else
        {
            Delog($"Type: {typeName}");
        }
    }

    public static void ErrorLog(object message)
    {
        Debug.LogError(message);
    }

    public static void DelogWarning(object message)
    {
        stupid.Debug.Warning(message);
    }

    public static void DelogError(object message)
    {
        stupid.Debug.Error(message);
    }

    public static void print(object variable, string comment = "")
    {
        Print(variable, comment);
    }

    public static void Print(object variable, string comment = "")
    {
        if (string.IsNullOrEmpty(comment))
        {
            comment = null; // 不显示注释
        }

        if (variable == null)
        {
            variable = "null";
        }

        Type variableType = variable.GetType();

        if (variableType.IsPrimitive || variable is string)
        {
            if (comment != null)
                Debug.Log($"{comment}: {variable}");
            else
                Debug.Log(variable);
        }
        else if (variable is IEnumerable enumerable)
        {
            StringBuilder sb = new StringBuilder();
            if (comment != null)
                sb.AppendLine($"{comment}:");
            int index = 0;
            foreach (var item in enumerable)
            {
                sb.AppendLine($"  [{index}]: {item}");
                index++;
            }

            Debug.Log(sb.ToString());
        }
        else if (variable is IDictionary dictionary)
        {
            StringBuilder sb = new StringBuilder();
            if (comment != null)
                sb.AppendLine($"{comment}:");
            foreach (DictionaryEntry entry in dictionary)
            {
                sb.AppendLine($"  [{entry.Key}]: {entry.Value}");
            }

            Debug.Log(sb.ToString());
        }
        else
        {
            StringBuilder sb = new StringBuilder();
            if (comment != null)
                sb.AppendLine($"{comment} ({variableType.Name}):");
            else
                sb.AppendLine($"{variableType.Name}:");
            PropertyInfo[] properties = variableType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo property in properties)
            {
                try
                {
                    object propertyValue;

                    // 判断是否是索引器（比如 this[int index]）
                    ParameterInfo[] indexParams = property.GetIndexParameters();
                    if (indexParams.Length > 0)
                    {
                        // 是索引器，这里可以尝试传默认值（如 0），或者跳过
                        // 注意：有些索引器需要多个参数，处理起来更复杂
                        if (indexParams[0].ParameterType == typeof(int))
                        {
                            propertyValue = property.GetValue(variable, new object[] { 0 });
                        }
                        else
                        {
                            propertyValue = $"Indexed property with type [{indexParams[0].ParameterType.Name}], not supported here.";
                        }
                    }
                    else
                    {
                        // 普通属性，无需参数
                        propertyValue = property.GetValue(variable);
                    }

                    sb.AppendLine($"  {property.Name}: {propertyValue}");
                }
                catch (TargetInvocationException ex)
                {
                    sb.AppendLine($"  {property.Name}: Error accessing property - {ex.InnerException?.Message}");
                }
                catch (TargetParameterCountException ex)
                {
                    sb.AppendLine($"  {property.Name}: Parameter mismatch - {ex.Message}");
                }
                catch (Exception ex)
                {
                    sb.AppendLine($"  {property.Name}: Unexpected error - {ex.Message}");
                }
            }

            Debug.Log(sb.ToString());
        }
    }

    #endregion
}